<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>嵌套表格</title>
    <script th:inline="javascript">
        // 初始化鼠标浮过行时高亮显示
        function bindNestTableMouseEvent() {
            $("table[id^='nestTable_'] td").mouseout(function () {
                // nestTable没有thead，所以$(this).parent().parent()必为tbody
                // 获得td是在第几行
                var trIndex = $(this).parent().parent().find("tr").index($(this).parent()[0]);
                if (trIndex != 0) {
                    $(this).parent().find("td").each(function (i) {
                        $(this).removeClass("tdOver");
                    });
                }
            });

            $("table[id^='nestTable_'] td").mouseover(function () {
                var trIndex = $(this).parent().parent().find("tr").index($(this).parent()[0]);
                if (trIndex != 0) {
                    $(this).parent().find("td").each(function (i) {
                        $(this).addClass("tdOver");
                    });
                }
            });
        }

        // 按行分组
        function autoMergeCells(table, isPropStat, dlt, rowGroupFields) {
            var op = [[${op}]];
            // 编辑状态不支持按行分组合并
            var isShowPage = op.indexOf("show")!=-1;
            console.log('isShowPage', isShowPage);
            if (!isShowPage) {
                // 如果编辑时合并，则字段需为不可写方可合并，但编辑时合并会导致calcFields中取列数的时候不对
                return;
            }

            const rows = table.rows;
            let rowLen = isPropStat ? rows.length - 1 : rows.length;
            for (let col = rows[0].cells.length - 1; col >=dlt ; col--) {
                if (rowGroupFields.some((val) => (val + dlt) == col)) {
                    console.log('col', col, 'dlt', dlt);
                    for (let row = rowLen-1; row >= 1 ; row--) {
                        const currentCell = rows[row].cells[col];
                        const previousCell = rows[row - 1].cells[col];
                        // console.log(currentCell.textContent + '--' + previousCell.textContent)
                        if (currentCell.textContent === previousCell.textContent) {
                            let isSame = true;
                            // 判断其左侧的每一列，内容是否相同，如果相同，才能合并，当col为<=dlt时时，是复选框列、序号列
                            for (let colIndex = col; colIndex>=dlt+1; colIndex--) {
                                const currentCellLeft = rows[row].cells[colIndex-1];
                                const previousCellLeft = rows[row - 1].cells[colIndex-1];
                                if (currentCellLeft.textContent != previousCellLeft.textContent) {
                                    isSame = false;
                                    break;
                                }
                            }
                            if (!isSame)
                                continue;

                            console.log('currentCell', currentCell, 'col', col);
                            previousCell.setAttribute('rowspan', (currentCell.rowSpan || 1) + 1);
                            currentCell.parentNode.removeChild(currentCell);
                        }
                    }
                }
            }
        }

        function autoMergeHeaders(table, dlt, groupFields) {
            if (!table) {
                // 当嵌套表不可写时，table为undefined
                return;
            }
            const rows = table.rows;
            let leftHeader = '', curHeader = '';
            let curIndex = -1;
            let children = '';
            let row = rows[0];
            for (let col = 0; col < row.cells.length; col++) {
                if (col < dlt) {
                    row.cells[col].setAttribute("rowspan", 2);
                    continue;
                }
                curHeader = groupFields[col - dlt];
                console.log('curHeader', curHeader, 'col', col, 'dlt', dlt);
                if (!curHeader) {
                    console.log('no group', row.cells[col]);
                    row.cells[col].setAttribute("rowspan", 2);
                    leftHeader = '';
                    curIndex = -1;
                } else {
                    console.log('group', row.cells[col]);
                    if (curHeader != leftHeader) {
                        leftHeader = curHeader;
                        row.cells[col].setAttribute("colspan", 1);
                        $(row.cells[col]).text(curHeader);
                        $(row.cells[col]).attr('align', 'center');
                        curIndex = col;
                        children += $(row.cells[col]).prop('outerHTML');
                    } else {
                        var colspan = parseInt(row.cells[curIndex].getAttribute("colspan"));
                        row.cells[curIndex].setAttribute("colspan", colspan + 1);
                        children += $(row.cells[col]).prop('outerHTML');
                        row.cells[col].parentNode.removeChild(row.cells[col]);
                        console.log('row.cells[' + col + '].parentNode', row.cells[col].parentNode);
                        col --;
                        dlt --;
                    }
                }
            }

            console.log('children', children);
            $(table.rows[0]).after(children);
        }
    </script>
</head>
<body>
<th:block th:if="${opContainsShow}">
    [(${viewForm})]

    <script th:inline="javascript">
        console.log('viewForm show');

        var isPageShow = [(${isPageShow})];
        var isNoShow = [(${isNoShow})];
        // 增加序号列
        var tdHeaderCheckbox = "<td width=\"55\" rowspan=\"[(${headerRows})]\" style=\"display: " + (isNoShow==1?"":"none") + "\" align=\"center\" valign=\"middle\">序号</td>";
        $("#nestTable_[(${nestFieldName})] tr").first().prepend(tdHeaderCheckbox);

        if (isPageShow) {
            // 置主表中计算控件的值
            var nestSheetSums = [(${jsonSums})];
            console.log('nest_cell_view nestSheetSums', nestSheetSums, 'formCode', '[(${formCode})]');
            var keys = '';
            // 注意此处不能用 for(var o in nestSheetSums) ，因为会覆盖全局的 o函数
            for (var key in nestSheetSums) {
                if (keys.indexOf(',' + key + ',') != -1) {
                    // 跳过已正常取得的字段，因为可能在sum时两个嵌套表中都含有同名的字段，而其中一个是有formCode属性的
                    continue;
                }
                console.log('keys', keys);
                var $ctl = $("span[id='" + key + "'][formCode='[(${formCode})]']");
                if (!$ctl[0]) {
                    // 向下兼容会带来问题，如果在sum时两个嵌套表中都含有同名的字段，会导致出现问题，故需带有formCode属性的计算控件字段记住
                    // 向下兼容，旧版的sum型计算控件中没有formCode
                    $ctl = $("span[id='" + key + "']");
                } else {
                    if (keys == '') {
                        keys = ',' + key + ',';
                    } else {
                        keys += key + ',';
                    }
                }
                $ctl.html(nestSheetSums[key]);
            }
        }

        bindNestTableMouseEvent();

        // 将嵌套表格所在单元格的padding置为0
        $('#nestsheet_[(${nestFieldName})]').closest('td').css('padding', '0');

        // 按行分组合并单元格
        // 匿名函数
        (function () {
            var isShowChk = false;
            var isNoShow = true; // 序号列其实是隐藏了，该列始终都存在
            var isPropStat = [(${isPropStat})]
            var dlt = 0;
            if (isShowChk) {
                dlt += 1;
            }
            if (isNoShow) {
                dlt += 1;
            }

            let rowGroupFields = [(${rowGroupFields})];
            console.log('rowGroupFields', rowGroupFields);
            if (rowGroupFields.length > 0) {
                autoMergeCells($("#nestTable_[(${nestFieldName})]")[0], isPropStat, dlt, rowGroupFields);
            }
        })();

        // 对表头进行分组
        // 匿名函数
        (function () {
            var isFormView = [(${formViewId})] != -1;
            if (isFormView) {
                return;
            }
            var isShowChk = true;
            var isNoShow = [(${isNoShow})] == 1;
            var dlt = 0;
            if (isShowChk) {
                dlt += 1;
            }
            if (isNoShow) {
                dlt += 1;
            }

            let groupFields = [(${groupFields})];
            let isGroup = false;
            for (let j in groupFields) {
                if (groupFields[j]) {
                    isGroup = true;
                    break;
                }
            }
            if (isGroup) {
                autoMergeHeaders($("#nestTable_[(${nestFieldName})]")[0], dlt, groupFields);
            }
        })();
    </script>
</th:block>
<th:block th:if="${!opContainsShow}">
    [(${viewFormAndOuterHtmls})]
    <!--因setCtlValue速度慢，所以在此不运行，而是在后台NestTableNodeVisitorHelper中赋值-->
    <!--[(${scripts})]-->
    <!--scriptsForDisableAndHide中原来用的是DisableCtl方式，会导致速度更慢-->
    [(${scriptsForDisableAndHide})]
<code th:id="'tmpTableHtml' + ${nestFieldName}" style="display: none">[(${tmpHtml})]</code>
<code th:id="'tmpDisableScript' + ${nestFieldName}" style="display: none">[(${scriptsForDisableAndHideForAdd})]</code>
<script th:inline="javascript">
    console.log('viewForm edit');

    var rowId[(${nestFieldName})] = [(${rowId})];
    // 添加新行时所用的html，里面含tr、td及已解析好的控件
    var $nestTr[(${nestFieldName})];

    console.log('nest_cell_view init');

    function getIframeContent[(${nestFieldName})]() {
        var html = unescape($('#tmpTableHtml[(${nestFieldName})]').html());
        console.log('getIframeContent', html);
        return html;
    }

    // 置添加时新行中的元素
    function setNestTr[(${nestFieldName})](html) {
        // 重新生成元素，否则因为之后删除了iframe，IE中会报没有权限
        $nestTr[(${nestFieldName})] = $(html);

        var isAddHighlight = [(${isAddHighlight})];
        if (isAddHighlight==1) {
            $nestTr[(${nestFieldName})].addClass('row-add');
        }
    }

    // 如果没有则创建，因为当配置了自动拉单时，会在拉单时再次调用nest_cell_view
    if (!$('#iframe[(${nestFieldName})]')[0]) {
        // 在containerDiv获取辅助表格的tr，以免当存在与主表同名的字段时，scriptsForDisableAndHideForAdd中的脚本在disable时会带来影响
        var html = getIframeContent[(${nestFieldName})]();
        var containerDiv = document.createElement("DIV");
        containerDiv.innerHTML = '<div id="container[(${nestFieldName})]">' + html + '</div>';
        var $nestTr = $(containerDiv).find("#tableHelper tr");
        setNestTr[(${nestFieldName})]($nestTr.prop('outerHTML'));
    }

    // 初始化日期控件
    // console.log("init nest table");

    // 将嵌套表格所在单元格的padding置为0
    $('#nestsheet_[(${nestFieldName})]').closest('td').css('padding', '0');

    // 加入工具条
    var toolbar = "<div id='toolbar_[(${nestFieldName})]' class='nest-toolbar'>";

    var queryId = [(${queryId})];
    var op = '[(${op})]';
    var canAdd = [(${canAdd})];
    var canDel = [(${canDel})];
    var canImport = [(${canImport})];
    var canExport = [(${canExport})];
    var canSel = [(${canSel})];

    if (("edit" == op || "add" == op) && canAdd) {
        toolbar += "<span class='nest-btn' onclick='addNestTr[(${nestFieldName})]([(${isPropStat})])'><i class=\"fa fa-plus-circle link-icon link-icon-add\"></i>添加</span>";
    }

    if (("edit" == op || "add" == op) && canDel) {
        toolbar += "<span class='nest-btn' onclick='delNestTr(\"[(${nestFormCode})]\", \"[(${nestFieldName})]\")'><i class=\"fa fa-trash-o link-icon link-icon-del\"></i>删除</span>";
    }

    if ("edit" == op && canImport) {
        toolbar += "<span class='nest-btn' onclick='importExcel[(${nestFieldName})]()'><i class=\"fa fa-arrow-circle-o-down link-icon link-icon-edit\"></i>导入</span>";
    }

    if ("edit" == op && canExport) {
        toolbar += "<span class='nest-btn' onclick='exportExcel[(${nestFieldName})]()'><i class=\"fa fa-arrow-circle-o-up link-icon link-icon-edit\"></i>导出</span>";
    }

    // 模块添加页面不支持拉单，因为拉单后会刷新嵌套表格，而此时parentId为-1，无法关联记录
    // if ("edit".equals(op) && canSel) {
    if (canSel) {
        if (queryId!=-1) {
            toolbar += "<span class='nest-btn' onclick='sel[(${nestFieldName})]([(${cwsId})], true)'><i class=\"fa fa-check-square-o link-icon link-icon-show\"></i>选择</span>";
        }
        else {
            toolbar += "<span class='nest-btn' onclick='sel[(${nestFieldName})]([(${cwsId})])'><i class=\"fa fa-check-square-o link-icon link-icon-show\"></i>选择</span>";
        }
    }

    toolbar += "</div>";
    $("#nestTable_[(${nestFieldName})]").before(toolbar);
    var isNoShow = [(${isNoShow})];

    // 增加checkbox列
    var tdHeaderCheckbox = "<td width=\"50\" rowspan=\"[(${headerRows})]\" align=\"center\" valign=\"middle\"><input id='chk[(${nestFieldName})]' type='checkbox'/></td><td rowspan=\"[(${headerRows})]\" style=\"display: " + (isNoShow==1?"":"none") + "\" width='55' align='center'>序号</td>";
    $("#nestTable_[(${nestFieldName})] tr").first().prepend(tdHeaderCheckbox);
    $('#chk[(${nestFieldName})]').click(function() {
        if ($(this).prop("checked")) {
            $('#nestTable_[(${nestFieldName})]').find("input[name='chk[(${nestFieldName})]'][type=checkbox]").prop("checked", true);
        }
        else {
            $('#nestTable_[(${nestFieldName})]').find("input[name='chk[(${nestFieldName})]'][type=checkbox]").prop("checked", false);
        }
    });

    if ("add" != op) {
        // 初始化表格中已有的数据行
        var headerRows = [(${headerRows})];
        $("#nestTable_[(${nestFieldName})] tr").each(function(index) {
            if (index >= headerRows) {
                initTr('[(${nestFieldName})]', $(this), index - headerRows, false);
            }
        });
    }

    $('#toolbar_[(${nestFieldName})]').on('mouseover', '.nest-btn', function(e) {
        $(this).addClass("nest-btn-hover");
    });
    $('#toolbar_[(${nestFieldName})]').on('mouseout', '.nest-btn', function(e) {
        $(this).removeClass("nest-btn-hover");
    });

    // 初始化序号
    initTdNo('[(${nestFieldName})]');

    var isTrStatAdded[(${nestFieldName})] = false;
    if (rowId[(${nestFieldName})] > 0) {
        isTrStatAdded[(${nestFieldName})] = true;
    }

    // 添加行
    function addNestTr[(${nestFieldName})](isPropStat) {
        console.log('addNestTr');
        if (isPropStat) {
            // 在统计行之前插入
            var $curLastTr = $('#nestTable_[(${nestFieldName})] tr').last();
            // 在发起流程时表格一开始为空，没有统计行，即只有表头那一行，其prev()为undefined
            if (!$curLastTr.prev()[0]) {
                $curLastTr.after($nestTr[(${nestFieldName})].clone());
                $lastTr = $("#nestTable_[(${nestFieldName})] tr").last();
            }
            else {
                $('#nestTable_[(${nestFieldName})] tr').last().prev().after($nestTr[(${nestFieldName})].clone());
                $lastTr = $("#nestTable_[(${nestFieldName})] tr").last().prev();
            }
            // clone后得到的tr需要再次初始化日期控件
            initTr('[(${nestFieldName})]', $lastTr, rowId[(${nestFieldName})], true);
        }
        else {
            // 替换添加新行 $nestTr 中的 macroJsModuleFieldSelectCtl?***，以使得 addChangeListener 能正确绑定
            var $newTr = $nestTr[(${nestFieldName})].clone();
            console.log('$newTr[0]', $newTr.prop('outerHTML'));
            var newTr = $newTr.prop('outerHTML').replaceAll('macroJsModuleFieldSelectCtl\\?', 'macroJsModuleFieldSelectCtl?nestFieldName=[[${nestFieldName}]]&nestTableRowId=' + rowId[(${nestFieldName})] + '&');

            $('#nestTable_[(${nestFieldName})]').append(newTr);

            var script = o('tmpDisableScript[(${nestFieldName})]').innerHTML;
            console.log('tmpDisableScript', script);
            eval(script);

            $lastTr = $("#nestTable_[(${nestFieldName})] tr").last();
            // clone后得到的tr需要再次初始化日期控件
            initTr('[(${nestFieldName})]', $lastTr, rowId[(${nestFieldName})], true);
        }

        // 添加统计行，注意只能添加一次
        if (isPropStat) {
            if (!isTrStatAdded[(${nestFieldName})]) {
                $lastTr.after("[(${trStatHtml})]");
                isTrStatAdded[(${nestFieldName})] = true;
            }
        }

        rowId[(${nestFieldName})] ++;
        // 初始化序号
        initTdNo('[(${nestFieldName})]');

        bindNestTableMouseEvent();
    }

    function delTr(nestFormCode, nestFieldName, $trs) {
        var ids = '';
        $trs.each(function () {
            var id = $('#nest_field_dataId' + nestFieldName + '_' + $(this).val()).val();
            if (id == undefined) {
                // 如果为空，则为新增的记录，而非选择的记录，直接删除
                $(this).parent().parent().remove();
                initTdNo(nestFieldName);
                callCalculateOnloadNestTable('nestTable_[(${nestFieldName})]');
                return;
            }
            if (ids == '') {
                ids = id;
            }
            else {
                ids += ',' + id;
            }
        });
        if (ids == '') {
            return;
        }
        var ajaxData = {
            ids: ids,
            formCode: nestFormCode
        };
        let path = '/flow/macro/delNestTableRows';
        ajaxPost(path, ajaxData).then((data) => {
            // console.log('data', data);
            if (data.ret=="1") {
                // 删除原在数据库中已存在的行
                $trs.each(function () {
                    $(this).parents("tr:eq(0)").remove();
                });

                initTdNo(nestFieldName);
                callCalculateOnloadNestTable('nestTable_[(${nestFieldName})]');
            }
            else {
                myMsg(data.msg);
            }
        });
    }

    // 删除行
    function delNestTr(nestFormCode, nestFieldName) {
        var $trs = $("input[type=checkbox][name='chk" + nestFieldName + "']:checked");
        if ($trs.length == 0) {
            myMsg('请选择记录', 'warning');
            return;
        }
        myConfirm('提示', '您确定要删除么', function() { delTr(nestFormCode, nestFieldName, $trs) });
    }

    function importExcel[(${nestFieldName})]() {
        openImportExcelModal("[(${cwsId})]", "[(${formCode})]", "[(${parentFormCode})]", [(${flowId})], "[(${nestFieldName})]", "nest_table");
    }

    function exportExcel[(${nestFieldName})]() {
        exportExcelRelate(
            [[${NEST_TYPE_NORMAIL}]],
            '[(${cwsId})]',
            '[(${parentFormCode})]',
            '[(${formCode})]',
            '[(${formName})]',
        )
    }

    function sel[(${nestFieldName})](parentId, isQuery) {
        openWinModuleListNest("[(${parentFormCode})]", "[(${formCode})]", "[(${nestFieldName})]", "nest_table", parentId, parentId, "[(${condFields})]");
    }

    // 初始化序号
    function initTdNo(nestFieldName) {
        var k = 1;
        $("#nestTable_" + nestFieldName + " tr").each(function (index) {
            var $tdNo = $(this).find('.td-no');
            if ($tdNo[0]) {
                $tdNo.html(k);
                k++;
            }
        });
    }

    initNestTableCalculate('nestTable_[(${nestFieldName})]', '[(${nestFieldName})]');
    bindNestTableMouseEvent();

    $('input, select, textarea').each(function() {
        $(this).attr('autocomplete', 'off');
    });

    // 按行合并单元格
    // 匿名函数
    (function () {
        var isShowChk = true;
        var isNoShow = [(${isNoShow})]==1;
        var isPropStat = [(${isPropStat})];
        var dlt = 0;
        if (isShowChk) {
            dlt += 1;
        }
        if (isNoShow) {
            dlt += 1;
        }

        let rowGroupFields = [(${rowGroupFields})];
        console.log('rowGroupFields', rowGroupFields);
        if (rowGroupFields.length > 0) {
            autoMergeCells($("#nestTable_[(${nestFieldName})]")[0], isPropStat, dlt, rowGroupFields);
        }
    })();

    // 匿名函数
    (function () {
        // 对表头进行分组
        var formViewId = [(${formViewId})];
        var isFormView = formViewId != -1;
        if (isFormView) {
            return;
        }
        var isShowChk = true;
        var isNoShow = [(${isNoShow})] == 1;
        var dlt = 0;
        if (isShowChk) {
            dlt += 1;
        }
        if (isNoShow) {
            dlt += 1;
        }

        let groupFields = [(${groupFields})];
        let isGroup = false;
        for (let j in groupFields) {
            if (groupFields[j]) {
                isGroup = true;
                break;
            }
        }
        if (isGroup) {
            autoMergeHeaders($("#nestTable_[(${nestFieldName})]")[0], dlt, groupFields);
        }
    })();
</script>
</th:block>
</body>
</html>
